using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using Identity.Application.Contracts.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;

namespace Identity.HttpAPI.Permission;

public class MixedPermissionHandler : AuthorizationHandler<PermissionRequirement>
{
    private readonly IPermissionCenterService _permissionCenter;
    private readonly IPermissionBindingService _permissionBindingService;

    public MixedPermissionHandler(IPermissionCenterService permissionCenter, IPermissionBindingService permissionBindingService)
    {
        _permissionCenter = permissionCenter;
        _permissionBindingService = permissionBindingService;
    }

    protected override async Task HandleRequirementAsync(
        AuthorizationHandlerContext context,
        PermissionRequirement requirement)
    {
        var userId = context.User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
        if (string.IsNullOrEmpty(userId))
        {
            context.Fail();
            return;
        }

        var permAttr = GetPermissionAttribute(context.Resource);
        if (permAttr == null)
        {
            return; // 没有打标记的就跳过
        }

        // 从数据库查映射 (role:items:Get → Role.Get)
        var mappedPermission = await _permissionBindingService.GetMappedPermissionKeyAsync(permAttr.ResourceId);
        if (string.IsNullOrEmpty(mappedPermission))
        {
            context.Fail();
            return;
        }

        // 1️⃣ 本地 Claims 检查
        var userPermissions = context.User.FindAll("permission").Select(c => c.Value);
        if (userPermissions.Contains(mappedPermission))
        {
            context.Succeed(requirement);
            return;
        }

        // 2️⃣ 中心化校验兜底
        if (!string.IsNullOrEmpty(userId))
        {
            bool granted = await _permissionCenter.UserHasPermissionAsync(userId, mappedPermission);
            if (granted)
            {
                context.Succeed(requirement);
                return;
            }
        }

        context.Fail();


    }

    /// <summary>
    /// 从 Resource 中解析 PermissionAttribute (兼容 MVC + Endpoint routing)
    /// </summary>
    private static PermissionAttribute? GetPermissionAttribute(object? resource)
    {
        switch (resource)
        {
            case AuthorizationFilterContext mvcContext:
                var actionDesc = mvcContext.ActionDescriptor as ControllerActionDescriptor;
                return actionDesc?.MethodInfo
                    .GetCustomAttributes(typeof(PermissionAttribute), false)
                    .FirstOrDefault() as PermissionAttribute;

            case HttpContext httpContext:
                var endpoint = httpContext.GetEndpoint();
                return endpoint?.Metadata.GetMetadata<PermissionAttribute>();

            default:
                return null;
        }
    }
}